﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Net.Mail;
using System.IO;
using System.Diagnostics;
using System.Text;

namespace SubversionEmailer
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (args.Length < 2)
            {
                return;
            }

            //
            // Exceptions should not be caught.  TourtoiseSVN will catch them for us and display the error message on check-in.
            //

            string projectName = "Project Checkin";
            MailMessage message = new MailMessage("subversion.emailer@gmail.com", "subversion.emailer@gmail.com", "subject", "body");
            
            string[] allLines = null;
            allLines = File.ReadAllLines(args[0] + @"\hooks\emailer-options.txt");
            for (int lineIndex = 0; lineIndex < allLines.Length; lineIndex++)
            {
                string curLine = allLines[lineIndex];
                string[] curWords = curLine.Split(':');
                if (curWords.Length == 2)
                {
                    string command = curWords[0];
                    if (command == "name")
                    {
                        projectName = curWords[1];
                    }
                    else if (command == "to")
                    {
                        message.To.Add(new MailAddress(curWords[1]));
                    }
                    else
                    {
                        //
                        // Unrecognized command
                        //
                    }
                }
            }

            message.Sender = new MailAddress("subversion.emailer@gmail.com");
            SmtpClient emailClient = new SmtpClient("smtp.gmail.com");
            System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential("subversion.emailer@gmail.com", "*verysecret*");

            message.Subject = "[" + projectName + "] r" + args[1];
            //message.Body = BuildCommitMessage(@"C:\csvn\data\repositories\projects_v2", "39");
            message.Body = BuildCommitMessage(args[0], args[1]);

            emailClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            emailClient.EnableSsl = true;
            emailClient.Port = 587;
            emailClient.UseDefaultCredentials = false;
            emailClient.Credentials = SMTPUserInfo;

            emailClient.Send(message);
        }

        private static string BuildCommitMessage(string repository, string revision)
        {
            StringBuilder result = new StringBuilder();
            
            result.Append("Author: " + GetRepoInfo(repository, revision, "author"));
            result.AppendLine(String.Format("{0:G}", DateTime.Now));
            
            result.AppendLine();
            result.AppendLine("Modified:");
            result.Append(GetRepoInfo(repository, revision, "changed"));

            result.AppendLine();
            result.AppendLine("Log:");
            result.Append(GetRepoInfo(repository, revision, "log"));

            result.AppendLine();
            result.Append(GetRepoInfo(repository, revision, "diff"));

            return result.ToString();
        }

        private static string GetRepoInfo(string repository, string revision, string command)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = "svnlook";
            p.StartInfo.Arguments = command + " -r " + revision + " " + repository;
            p.Start();
            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            return output;
        }
    }
}
